package com.zq.assistant.func.apifactory.invocationhandler;

import com.zq.assistant.app.Config;
import com.zq.assistant.func.apifactory.annotation.HttpMethod;
import com.zq.assistant.func.apifactory.annotation.Mode;
import com.zq.assistant.func.apifactory.annotation.RequestCallback;
import com.zq.assistant.func.apifactory.annotation.RequestMethod;
import com.zq.assistant.func.apifactory.annotation.RequestParam;
import com.zq.assistant.func.apifactory.annotation.RequestPath;
import com.zq.assistant.func.apifactory.annotation.RequestSync;
import com.zq.assistant.func.apifactory.annotation.RequestTag;
import com.zq.assistant.func.apifactory.api.LifeCycle;
import com.zq.assistant.func.apifactory.callback.ResultCallback;
import com.zq.assistant.func.apifactory.handler.HttpRequestHandler;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * Created by zhangqiang on 2016/8/3.
 */
public class HttpInvocationHandler implements InvocationHandler {

    private HttpRequestHandler httpRequestHandler;

    public HttpInvocationHandler(HttpRequestHandler httpRequestHandler) {
        this.httpRequestHandler = httpRequestHandler;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if("bindLifeCycle".equals(method.getName())){

            this.httpRequestHandler.bindLifeCycle((LifeCycle) args[0]);
            return null;
        }
        if("cancel".equals(method.getName())){
            this.httpRequestHandler.cancel();
            return null;
        }

        //获取URL
        String requestUrl;

        RequestPath path = method.getAnnotation(RequestPath.class);
        if (path == null) {

            throw new IllegalArgumentException("");
        }

        //构造请求url
        requestUrl = Config.getBaseApi() + path.value();

        //获取参数
        Annotation[][] annotations = method.getParameterAnnotations();
        ArrayList<HttpParam> httpParams = new ArrayList<>();
        Object tag = null;
        ResultCallback<?> callback = null;
        Class<?> callbackGenericClass = null;
        Class<?> callbackGenericClass2 = null;

        //遍历参数
        for (int i = 0; i < annotations.length; i++) {

            Object arg = args[i];
            if (arg == null) {
                continue;
            }
            //遍历参数的注解
            for (int j = 0; j < annotations[i].length; j++) {

                Annotation annotation = annotations[i][j];

                if (annotation instanceof RequestParam) {

                    //如果是参数的注解
                    RequestParam requestParam = (RequestParam) annotation;
                    HttpParam httpParam = new HttpParam();
                    httpParam.setKey(requestParam.key());
                    httpParam.setValue(arg);
                    httpParams.add(httpParam);
                } else if (annotation instanceof RequestTag) {

                    //如果是tag
                    tag = arg;
                } else if (annotation instanceof RequestCallback) {

                    RequestCallback requestCallback = (RequestCallback) annotation;
                    callback = (ResultCallback<?>) arg;
                    callbackGenericClass = requestCallback.genericClass();
                    callbackGenericClass2 = requestCallback.genericClass2();
                }
            }
        }
        //获取请求方法
        HttpMethod httpMethod = HttpMethod.GET;
        Class returnClass = null;
        Class<?> returnGenericClass = null;
        RequestMethod requestMethod = method.getAnnotation(RequestMethod.class);
        if (requestMethod != null) {
            httpMethod = requestMethod.value();
        }

        //请求模式
        Mode mode = Mode.ASYNC;
        RequestSync requestSync = method.getAnnotation(RequestSync.class);
        if (requestSync != null) {

            mode = Mode.SYNC;
            returnGenericClass = requestSync.genericClass();
            returnClass = method.getReturnType();
        }

        //构建http请求
        HttpRequest httpRequest = new HttpRequest();
        httpRequest.setUrl(requestUrl);
        httpRequest.setHttpMethod(httpMethod);
        httpRequest.setMode(mode);
        httpRequest.setTag(tag);
        httpRequest.setParams(httpParams);
        httpRequest.setCallback(callback);
        httpRequest.setCallbackGenericClass(callbackGenericClass);
        httpRequest.setReturnClass(returnClass);
        httpRequest.setReturnGenericClass(returnGenericClass);
        httpRequest.setCallbackGenericClass2(callbackGenericClass2);

        if (this.httpRequestHandler != null) {
            return this.httpRequestHandler.onHandleHttpRequest(httpRequest);
        }
        return null;
    }


}
